<?php

namespace App\Models\Cruise;

use App\Enums\Check\CheckEnum;
use App\Enums\OpenShop\InvestmentPromotion\ErrCode;
use App\Exceptions\Custom\CustomHttpResponseException;
use App\Models\BaseModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderPayHistoryModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopUserIdentityCardModel;
use App\Models\Traits\KfUid;
use App\Service\BaseService;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;

class CruiseCheckAgainstModel extends BaseModel
{
    use KfUid;

    protected $table    = 'cruise_check_against';
    protected $fillable = [
        'shopId',
        'cruiseCheckDetailId',
        'businessType',
        'businessId',
        'serialNum',
        'version',
        'price',
        'endTime',
        'level',
        'status',
        'type',
        'behaviorDesc',
        'rectifyPlan',
        'paidPrice',
        'payTime',
        'templateType',
        'updatedByUid',
        'startTime',
        'reason',
    ];

    const BUSINESS_TYPE_WEB     = 1; // 后台手动添加
    const BUSINESS_TYPE_ERROR   = 2; // 异常报备
    const BUSINESS_TYPE_RECTIFY = 3; // 整改违约

    const LEVEL_DEFAULT = 0;
    const LEVEL_WARNING = 1;
    const LEVEL_PUNISH  = 2;

    const LEVEL_TEXT = [
        self::LEVEL_DEFAULT => '',
        self::LEVEL_WARNING => '警告',
        self::LEVEL_PUNISH  => '处罚',
    ];

    const LEVEL_EN_NO = [
        self::LEVEL_DEFAULT => 'wy',
        self::LEVEL_WARNING => 'wyj',
        self::LEVEL_PUNISH  => 'wyc',
    ];

    const STATUS_WAIT    = 0;
    const STATUS_OK      = 1;
    const STATUS_CLOSE   = 2;

    const STATUS_TEXT = [
        self::STATUS_WAIT    => '未处理',
        self::STATUS_OK      => '已处理',
        self::STATUS_CLOSE   => '已关闭',
    ];

    const TYPE_SELF_MANAGE = 1;
    const TYPE_SHOP_QSC    = 2;

    const TYPE_MAP = [
        self::TYPE_SELF_MANAGE => 1,
        self::TYPE_SHOP_QSC    => 2,
    ];

    const TYPE_TEXT = [
        self::TYPE_SELF_MANAGE => '自采管理',
        self::TYPE_SHOP_QSC    => '门店QSC\运营管理',
    ];

    const TEMPLATE_TYPE_DEFAULT = 0;//违约函模板类型 0常规模板 1超时模板
    const TEMPLATE_TYPE_TIMEOUT = 1;

    const TEMPLATE_TYPE_MAP = [
        self::TEMPLATE_TYPE_DEFAULT => 1,
        self::TEMPLATE_TYPE_TIMEOUT => 2,
    ];

    const DEFAULT_END_TIME = 10 * 86400;//违约函处理时间

    const DEFAULT_TIMEOUT_PRICE = 2000;//超时违约函默认2000元

    /**
     * 添加违约函
     * @param int $shopId
     * @param int $cruiseCheckDetailId
     * @param int $businessType
     * @param int $businessId
     * @param string $serialNum
     * @param string $version
     * @param int $price
     * @param int $endTime
     * @param int $level
     * @param int $type
     * @param string $behaviorDesc
     * @param string $rectifyPlan
     * @return void
     */
    public static function add(int $shopId, int $cruiseCheckDetailId, int $businessType, int $businessId, string $serialNum, string $version, int $price, int $endTime, int $level, int $type, string $behaviorDesc, string $rectifyPlan)
    {
        self::query()->create([
            'shopId'              => $shopId,
            'cruiseCheckDetailId' => $cruiseCheckDetailId,
            'businessType'        => $businessType,
            'businessId'          => $businessId,
            'serialNum'           => $serialNum,
            'version'             => $version,
            'price'               => $price,
            'endTime'             => $endTime,
            'level'               => $level,
            'type'                => $type,
            'behaviorDesc'        => $behaviorDesc,
            'rectifyPlan'         => $rectifyPlan,
        ]);
    }


    /**
     * @return HasManyThrough
     */
    public function userIdentityCardRel(): HasManyThrough
    {
        return $this->hasManyThrough(
            OpenShopUserIdentityCardModel::class,
            OpenShopMainProcessModel::class,
            'shopId',
            'orderNo',
            'shopId',
            'orderNo');
    }

    /**
     * @return HasManyThrough
     */
    public function signOrderRel(): HasManyThrough
    {
        return $this->hasManyThrough(
            OpenShopSignOrderModel::class,
            OpenShopMainProcessModel::class,
            'shopId',
            'mainProcessId',
            'shopId',
            'id');
    }

    public function payHistoryRel(): HasMany
    {
        return $this->hasMany(OpenShopSignOrderPayHistoryModel::class, 'bizId', 'serialNum')
                    ->where('sysType', CheckEnum::SYS_TYPE_AGAINST);
    }

    /**
     * 新增违约函
     * @param array $data
     * @return Builder|Model
     */
    public static function addCheckAgainst(array $data)
    {
        return self::query()->create($data);
    }

    /**
     * 修改违约函
     * @param $id
     * @param $data
     * @return int
     */
    public static function setCheckAgainstInfoById($id, $data): int
    {
        return self::query()->where(['id' => $id])->update($data);
    }

    public function onePaySuccess(int $payPrice): self
    {
        // 已支付金额累加
        $this->paidPrice += $payPrice;

        if ($this->paidPrice == $this->price) {

            // 整单支付完成
            $this->status = self::STATUS_OK;
            $this->payTime   = time();
        } elseif ($this->paidPrice < $this->price) {

            // 部分支付完成

        } else {

            // 支付金额超过应付
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_PAY_PRICE_OVERFLOW)
            );
        }

        $this->save();

        return $this;
    }

    /**
     * 待处理的违约函
     * @param array $shopId
     * @return array
     */
    public function getWaitAgainstIds(array $shopIds): array
    {
        $result = [];

        self::query()
            ->whereIn('shopId', $shopIds)
            ->where('status', self::STATUS_WAIT)
            ->select('id', 'shopId', 'level')
            ->get()
            ->each(function ($item) use (&$result) {

                $result[$item['shopId']][] = [
                    'id'     => $item['id'],
                    'shopId' => $item['shopId'],
                    'level'  => $item['level'],
                ];
            });

        return $result;
    }
}
